#include "StdAfx.h"
#include "ComPorts.h"

ComPorts::ComPorts(HWND hMainWnd)
{
	Activated = true;
	// Open the serial port.

	hPort = CreateFile( TEXT("COM1:"), 
		GENERIC_READ | GENERIC_WRITE,
		1,
		NULL, 
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	dwError = GetLastError (); 

	if(dwError != 0) MessageBox (hMainWnd, TEXT("InitCOM fail"), 
		TEXT("Error"), MB_OK);

	SetTimeout();
	SetBitrate();

}

ComPorts::~ComPorts(void)
{
	BOOL closed;
	closed =  CloseHandle(hPort); 
}

bool ComPorts::SetBitrate()
{
	// Initialize the DCBlength member. 
	PortDCB.DCBlength = sizeof (DCB); 

	// Get the default port setting information.
	GetCommState (hPort, &PortDCB);

	// Change the DCB structure settings.
	PortDCB.BaudRate = 115200;              // Current baud 
	PortDCB.fBinary = TRUE;               // Binary mode; no EOF check 
	PortDCB.fParity = FALSE;               // Enable parity checking 
	PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control 
	PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control 
	PortDCB.fDtrControl = DTR_CONTROL_ENABLE; 
	// DTR flow control type 
	PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity 
	PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx 
	PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control 
	PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control 
	PortDCB.fErrorChar = FALSE;           // Disable error replacement 
	PortDCB.fNull = FALSE;                // Disable null stripping 
	PortDCB.fRtsControl = RTS_CONTROL_DISABLE;  	// RTS flow control 
	PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on error
	PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8 
	PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space 
	PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2 

	// Configure the port according to the specifications of the DCB 
	// structure.
	if (!SetCommState (hPort, &PortDCB))
	{
		// Could not configure the serial port.
		dwError = GetLastError ();
		MessageBox (hMainWnd, TEXT("Unable to configure the serial port"), 
			TEXT("Error"), MB_OK);
		return FALSE;
		Activated = false;
	}
	return true;
}
bool ComPorts::RTSEnable()
{

	// Change the DCB structure settings.
	// Disable null stripping 
	PortDCB.fRtsControl = RTS_CONTROL_ENABLE; 

	// Configure the port according to the specifications of the DCB 
	// structure.
	if (!SetCommState (hPort, &PortDCB))
		return false;
	else
		return true;
/*
		if(!EscapeCommFunction(hPort, SETRTS))
			dwError = GetLastError();
		return true;
		*/
}
bool ComPorts::RTSDisable()
{

	// Change the DCB structure settings.
	// Disable null stripping 
	PortDCB.fRtsControl = RTS_CONTROL_DISABLE; 

	// Configure the port according to the specifications of the DCB 
	// structure.
	if (!SetCommState (hPort, &PortDCB))
		return false;
	else
		return true;
/*
	if(!EscapeCommFunction(hPort, CLRRTS))
			dwError = GetLastError();
		return true;
		*/
}
bool ComPorts::DTREnable()
{
	
	// Change the DCB structure settings.
	PortDCB.fDtrControl = DTR_CONTROL_ENABLE; 

	// Configure the port according to the specifications of the DCB 
	// structure.
	if (!SetCommState (hPort, &PortDCB))
			return false;
	else
			return true;

}
bool ComPorts::DTRDisable()
{
	
	// Change the DCB structure settings.

	PortDCB.fDtrControl = DTR_CONTROL_DISABLE; 

	// Configure the port according to the specifications of the DCB 
	// structure.
	if (!SetCommState (hPort, &PortDCB))
		return false;
	else
		return true;

	
}
unsigned char ComPorts::SDA_value()
{
	//Modemstate
	DWORD dptr = 0; 

	if(!GetCommModemStatus (hPort, &dptr)) 	dwError = GetLastError();

	if(dptr & MS_CTS_ON)
		return 1;
	else 
		return 0;

}
inline void ComPorts::SDA_output()
{
		DTRDisable();
}
inline void ComPorts::SDA_input()
{
		DTREnable();
}
inline void ComPorts::SDA_low()
{
	DTRDisable();
	I2C_wait();
	I2C_wait();
	
}
inline void ComPorts::SDA_high()
{
	DTREnable();
	I2C_wait();
}
inline void ComPorts::SCL_low()
{
	RTSDisable();
	I2C_wait();
}
inline void ComPorts::SCL_high()
{
	RTSEnable();
	I2C_wait();
}
void ComPorts::I2C_wait()
{
	
	static DWORD dwOldTime= GetTickCount();

	while ((GetTickCount()-dwOldTime) <= 10)
	{
		;
	}
	
}
void ComPorts::I2C_start()
{
	SDA_output();
	SDA_high();
	SCL_high();
	SDA_low();
}
void ComPorts::I2C_stop()
{
	SDA_output();
	SDA_low();
	SCL_low();
	SCL_high();
	SDA_high();
	SDA_input();
}
void ComPorts::I2C_clock()
{
	SDA_output();
	SCL_high();
	I2C_wait(); 
	SCL_low();
}
void ComPorts::I2C_send_nack()
{
	SDA_output();
	SDA_high();
	SCL_high();
	SCL_low();
}
void ComPorts::I2C_send_ack()
{
	SDA_output();
	SDA_low();
	SCL_high();
	SCL_low();
	SDA_high();
}
bool ComPorts::I2C_read_ack()
{
	static unsigned char ret;
	ret= 0;
	SDA_input();
	SCL_low();
	SCL_high();
	ret = SDA_value();
	SCL_low();
	if(ret == 1)
		return false;
	else
		return true;
}

byte ComPorts::I2C_rx_byte()
{
	int i = 0;
	unsigned char retval = 0;

	byte i_byte, n;
	DWORD dptr = 0; 


	SDA_high();
	for (n=0; n<8; n++)
	{
		SCL_high();

		if(!GetCommModemStatus (hPort, &dptr)) 	dwError = GetLastError();

		if(dptr & MS_CTS_ON)
		{
			i_byte = (i_byte << 1) | 0x01; // msbit first
		}
		else
		{
			i_byte = i_byte << 1;
		}
		SCL_low();
	}
	return(i_byte);
}

void ComPorts::I2C_tx_byte(unsigned char o_byte)
{
	byte n;

	SDA_output();
	SCL_low();

	for(n=0; n<8; n++)
	{
		if(o_byte&0x80)
		{
			SDA_high();
		}
		else
		{
			SDA_low();
		}
		SCL_high();

		o_byte = o_byte << 1;
		SCL_low();
	}
	SDA_high();
}

bool ComPorts::SetTimeout()
{

	GetCommTimeouts (hPort, &CommTimeouts);

	// Change the COMMTIMEOUTS structure settings.
	CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
	CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
	CommTimeouts.ReadTotalTimeoutConstant = 0;    
	CommTimeouts.WriteTotalTimeoutMultiplier = 10;  
	CommTimeouts.WriteTotalTimeoutConstant = 1000;    

	// Set the timeout parameters for all read and write operations
	// on the port. 
	if (!SetCommTimeouts (hPort, &CommTimeouts))
	{
		// Could not set the timeout parameters.
		MessageBox (hMainWnd, TEXT("Unable to set the timeout parameters"), 
			TEXT("Error"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
	}
	return true;
}
bool ComPorts::WriteByte(BYTE Byte)
{
	DWORD  dwNumBytesWritten;

	WriteFile (hPort,              // Port handle
		(LPCVOID*)&Byte,              // Pointer to the data to write 
		1,                  // Number of bytes to write
		&dwNumBytesWritten, // Pointer to the number of bytes written
		NULL                // Must be NULL for Windows CE
		);

	if ( dwNumBytesWritten == 1)
		return true;
	else
		return false;

}
BYTE ComPorts::ReadByte()
{
	BYTE Byte;
	DWORD dwBytesTransferred;

	ReadFile (hPort,                // Port handle
		&Byte,                // Pointer to data to read
		1,                    // Number of bytes to read
		&dwBytesTransferred,  // Pointer to number of bytes read
		NULL                  // Must be NULL for Windows CE

		);


	if ( dwBytesTransferred == 1)
		return Byte;
	else
		return 0xFF;

}
